/**
 * Created by wyw on 2018/10/14.
 */
const Koa = require('koa');
const path = require('path');
const koaSend = require('koa-send');
const static = require('koa-static');
const socket = require('koa-socket');
const users = {}; // 保存用户
const sockS = {}; // 保存客户端对应的socket
const io = new socket({
    ioOptions: {
        pingTimeout: 10000,
        pingInterval: 5000,
    }
});

// 创建一个Koa对象表示web app本身:
const app = new Koa();
// socket注入应用
io.attach(app);
app.use(static(
    path.join(__dirname, './public')
));

// 对于任何请求，app将调用该异步函数处理请求：
app.use(async (ctx, next) => {
    if (!/\./.test(ctx.request.url)) {
        await koaSend(
            ctx,
            'index.html', {
                root: path.join(__dirname, './'),
                maxage: 1000 * 60 * 60 * 24 * 7,
                gzip: true,
            } // eslint-disable-line
        );
    } else {
        await next();
    }
});
// io.on('join', ctx=>{ // event data socket.id
// });
app._io.on('connection', sock => {
    sock.on('join', data => {
        sock.join(data.roomid, () => {
            if (!users[data.roomid]) {
                users[data.roomid] = [];
            }
            let obj = {
                account: data.account,
                isUserMedia: data.isUserMedia,
                id: sock.id
            };
            let arr = users[data.roomid].filter(v => v.account === data.account);
            if (!arr.length) {
                users[data.roomid].push(obj);
            }
            sockS[data.account] = sock;
            app._io.in(data.roomid).emit('joined', users[data.roomid], data.account, sock.id); // 发给房间内所有人
            // sock.to(data.roomid).emit('joined',data.account);
        });
    });
    sock.on('offer', data => {
        console.log('offer', data);
        sock.to(data.roomid).emit('offer', data);
    });
    sock.on('answer', data => {
        // console.log('answer', data);
        sock.to(data.roomid).emit('answer', data);
    });
    sock.on('__ice_candidate', data => {
        // console.log('__ice_candidate', data);
        sock.to(data.roomid).emit('__ice_candidate', data);
    });

    sock.on('message', data => {
        console.log('message', data);
        sock.to(data.roomid).emit('message', data);
    });
    
    // 1 v 1
    sock.on('apply', data => { // 转发申请
        sockS[data.account].emit('apply', data);
    });
    sock.on('reply', data => { // 转发回复
        sockS[data.account].emit('reply', data);
    });
    sock.on('1v1answer', data => { // 转发 answer
        sockS[data.account].emit('1v1answer', data);
    });
    sock.on('1v1ICE', data => { // 转发 ICE
        sockS[data.account].emit('1v1ICE', data);
    });
    sock.on('1v1offer', data => { // 转发 Offer
        sockS[data.account].emit('1v1offer', data);
    });
    sock.on('1v1hangup', data => { // 转发 hangup
        sockS[data.account].emit('1v1hangup', data);
    });
});
app._io.on('disconnect', (sock) => {
    for (let k in users) {
        users[k] = users[k].filter(v => v.id !== sock.id);
    }
    console.log(`disconnect id => ${users}`);
});

// 在端口3001监听:
let port = 9000;
app.listen(port, _ => {
    console.log('app started at port ...' + port);
});
// https.createServer(app.callback()).listen(3001);



// socket.broadcast.emit('user connected');
// 广播消息
// 要广播消息，只需要在 emit 和 send 方法前面加上 broadcast 标志即可。广播意味着将消息发送给除发送者以外的所有人。


// io.emit('chat message', msg);
// 我们将消息发送给所有用户，包括发送者。

// io.close();在关闭所有连接将被调用。
/*
命名空间就是不同的域 / new 与 / chat
var chat = io.connect('http://localhost:3000/chat');
var news = io.connect('http://localhost:3000/news');

io.of(chat)
io.of(news)
*/

/*
io.on('connect', onConnect);

function onConnect(socket){

  // 发送给当前客户端
  socket.emit('hello', 'can you hear me?', 1, 2, 'abc');

  // 发送给所有客户端，除了发送者
  socket.broadcast.emit('broadcast', 'hello friends!');

  // 发送给同在 'game' 房间的所有客户端，除了发送者
  socket.to('game').emit('nice game', "let's play a game");

  // 发送给同在 'game1' 或 'game2' 房间的所有客户端，除了发送者
  socket.to('game1').to('game2').emit('nice game', "let's play a game (too)");

  // 发送给同在 'game' 房间的所有客户端，包括发送者
  io.in('game').emit('big-announcement', 'the game will start soon');

  // 发送给同在 'myNamespace' 命名空间下的所有客户端，包括发送者
  io.of('myNamespace').emit('bigger-announcement', 'the tournament will start soon');

  // 发送给指定 socketid 的客户端（私密消息）
  socket.to(<socketid>).emit('hey', 'I just met you');

  // 包含回执的消息
  socket.emit('question', 'do you think so?', function (answer) {});

  // 不压缩，直接发送
  socket.compress(false).emit('uncompressed', "that's rough");

  // 如果客户端还不能接收消息，那么消息可能丢失
  socket.volatile.emit('maybe', 'do you really need it?');

  // 发送给当前 node 实例下的所有客户端（在使用多个 node 实例的情况下）
  io.local.emit('hi', 'my lovely babies');

};
*/